var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var util = require('imutil');
var Dialog = require('dialog');
var logger = require('logger');
var Session = require('session');
var SDK = require('sdk');
var sdk = null;

var Global = require('global');
var location = Global.location;
var navHistory = Global.history;

var bus = require('bus');

var meta = require('meta');

var User = require('../model/user');
var Users = require('../model/users');

var MainView = require('../view/main');
var ContactsView = require('../view/contacts');
var Chat2View = require('../view/chat2');
var ProfileView = require('../view/profile');

var Mask = require('mask');
var Loading = require('../biz/loading');
var Kickout = require('../biz/kickout');

var config = require('../webim.config');
var i18n = require('../i18n/index');
var servant = require('../i18n/servant.js');

var fastClick = require('fastclick');

// 最大重试次数
var MAX_RETRY_COUNT = 3;

// 客户端状态
var STATUS = {
	STARTED: 'STARTED',
	STOPED: 'STOPED',
	STARTING: 'STARTING',
	STOPPING: 'STOPPING'
};

/*
config.routes = {
	// 发布时路由配置
	"webim-touch" : "contacts",
	"webim-touch/contacts": "contacts",
	"webim-touch/chat2/:uid": "chat2",
	"webim-touch/chat2/:uid/:pid": "chat2",
	"webim-touch/profile/:uid": "profile"
};
*/

var PAGE_VIEWS = {
	contacts: ContactsView,
	chat2: Chat2View,
	profile: ProfileView
};

var App = Backbone.Router.extend({
	routes: config.routes,
	ready: function(fn){
		(typeof fn === 'function') && this._.ready.push(fn);
		
		this.checkReady();
	},
	checkReady: function(){
		if(this.isReady){
			while(this._.ready.length){
				this._.ready.shift().call(this);
			}
		}
	},
	initialize: function(){
		var _this = this;
		sdk = this.sdk = new SDK();
		
		this.config = config;
		
		this.isReady = false;
		this.isLogin = false;
		this.isGetContacts = false;
		this.isHistoryStart = false;
		this.status = STATUS.STOPED;
		
		this._ = {
			ready: []
		};
		
		this.cache = new Session("Global");
		
		this.models = {};
		this.views = {};
		
		this.util = util;
		//this.dialog = dialog;
		this.i18n = i18n;
		this.servant = servant;
		this.logger = logger;

		this.pages = {};
		this.currentPage = null;
		this.currentPageName = '';
		this.prevPageName = '';

		this.views.main = this.mainview = new MainView({}, this);
		this.mask = new Mask({el: this.views.main.$el});
		this.loading = new Loading({el: this.views.main.$body});
		this.kickout = new Kickout({el: this.views.main.$body});
		
		// 快速点击事件
		fastClick(this.views.main.$el[0]);
		
		// config Dialog
		Dialog.defaults.mask.el = this.views.main.$el;

		//
		this.models.user = new User();
		this.models.contacts = new Users();
		
		/*sdk.getContacts(function(contacts){
			_this.models.contacts.reset(contacts);
		});*/

		// 离线消息获取后，完成初始化
		this.listenTo(bus, 'leaveMessage', function(){
			this.isReady = true;
			this.checkReady();
		});
		
		// 获取联系人信息后，拉取离线消息
		this.listenTo(bus, 'contacts', function(){
			this.getLeaveMessage();
		});
		
		// 登录操作完成后，拉取最近联系人
		this.listenTo(bus, 'login', function(){
			this.getContacts();
		});
		
		// 登录
		this.listenTo(bus, 'login', function(){
			this.isLogin = true;
			this.loading.text('Fetch Contacts');
		});
		
		// 联系人数据获取后，重置 联系人 collection
		this.listenTo(bus, 'contacts', function(users){
			this.isGetContacts = true;
			users.sort(function(a,b){
				return b.lastChatTimestamp-a.lastChatTimestamp
			});
			
			this.reloadLocalContacts();
		});
		
		// 用户状态更新后，需要修改 联系人 在线相关属性
		this.listenTo(bus, 'statusChange', function(uid, isOnline){
			if(this.isGetContacts){
				var mUser = this.models.contacts.get(uid);
				var user = util.find(this.sdk.cache.get('contacts'), function(c){return c.id === uid});
				
				if(mUser && user){
					mUser.set({
						equipments: user.equipments,
						online: !!isOnline
					});
				}
			}
		});
		
		// 获取到离线消息后，修改联系人model的未读属性
		this.listenTo(bus, 'leaveMessage', function(){
			var contactsCollection = this.models.contacts;
			
			this.sdk.getContacts(function(contacts){
				util.each(contacts, function(user){
					var mUser = contactsCollection.get(user.id);
					
					if(mUser){
						mUser.set({
							unread: user.unread
						});
					}
				});
			});
		});
		
		/**
		* 接收到消息后，设置用户的未读数量
		*/
		this.listenTo(bus, 'receiveMessage messageSync', function(msg, strange){
			if(!strange){
				var mUser = this.models.contacts.get(msg.userId);
				if(mUser){
					this.sdk.getUserById(msg.userId, function(user){
						user && mUser.set(user);
					});
				}
			}else{
				this.sdk.getUserById(msg.userId, function(user){
					_this.models.contacts.add(new User(user));
				});
			}
		});
		
		// 被踢下线
		this.listenTo(bus, 'nty:kickout', function(){
			this.kickout.show();
			//_this.stop();
			this.nav.setModel({
				disabledNext: true,
				disabledMore: true
			});
		});
		
		this.kickout.on('relogin', function(){
			this.hide();
			
			_this.restart();
			
			_this.nav.setModel({
				disabledNext: false,
				disabledMore: false
			});
		});
		
		// 连接失效/失败
		this.listenTo(bus, 'connectFail', function(e){
			if(e.reason === "callback-connect-space-too-long"){ // 超时无响应
				// 延时是为了解决，当手机浏览器停止很长时间后，此账号被踢下线，导致的重新登录被踢下线操作断开连接
				setTimeout(function(){
					_this.restart();
				}, 100);
			}else{ // 连接异常
				
			}
		});
		
		// 连接成功
		/*this.listenTo(bus, 'connectSuccess', function(){
			
		});*/
		
		// 断开连接成功
		this.listenTo(bus, 'disconnectSuccess', function(){
			this.isReady = false;
			this.status = STATUS.STOPED;
			this.trigger('statusChange', {status: this.status});
			
			this.trigger('stop');
		});
		
		// 登录失败
		this.listenTo(bus, 'loginFail', function(e){
			logger.log(e.reason);
			this.loading.text(e.message);
			
			if(e.reason === 'empty-token'){
				Dialog.confirm('Relogin?', 'Login token invalid.', function(){
					// 空token最大可能是登录失效，重新进入登录界面
					Global.location.href = config.loginPage;
				});
			}else{
				Dialog.confirm('Restart?', e.message, function(){
					// 强行重启
					_this.stop();
					setTimeout(function(){
						_this.start();
					}, 1000);
				});
			}
			
		});
		
		this.hide();
	},
	contacts: function(){
		this.showView('contacts');
	},
	chat2: function(uid, pid){
		this.showView('chat2', uid || 0, pid);
	},
	profile: function(uid){
		this.showView('profile', uid || 0);
	},
	showView: function(viewname, uid, pid){
		this.show();
		
		for (var name in this.pages) {
			this.pages[name].remove();
		}

		this.pages[viewname] = new PAGE_VIEWS[viewname]({
			el: this.mainview.addPage(),
			i18n: this.i18n,
			args: [].slice.call(arguments, 1)
		}, this, uid, pid);

		this.prevPageName = this.currentPageName;
		this.currentPageName = viewname;
		this.currentPage = this.pages[viewname];
		
		bus.trigger('changePage', this.currentPage, this.currentPageName, uid);
	},
	// api
	forward: function(url){
		if(url){
			if(typeof url === 'number'){
				navHistory[url > 1 ? 'go' : 'forward'](url);
			}else{
				location.hash = this.path(url);
			}
		}else if(typeof url === 'undefined'){
			navHistory.forward();
		}
	},
	backward: function(step){
		step = step || 1;

		navHistory[step > 1 ? 'go' : 'back'](-step);
	},
	path: function(hash){
		return '#' + config.path + '/' + hash;
	},
	replaceUrl: function(url){
		navHistory.replaceState && navHistory.replaceState(null, "", location.href.replace(/\#.*$/, '') + this.path(url));
	},
	
	// exports api
	login: function(){
		this.sdk.login();
	},
	logout: function(){
		this.sdk.logout();
	},
	getContacts: function(){
		this.sdk.getContacts();
	},
	getLeaveMessage: function(){
		this.sdk.getLeaveMessages();
	},
	getUserByDomainUser: function(domainUser, cb){
		// 获取domian用户信息，必须登录完成
		this.ready(function(){
			this.sdk.getUserByDomainUser(domainUser, cb);
		});
	},
	
	// 显示/隐藏
	show: function(){
		$('html').addClass('webim-touch-html');
		sdk.screen.lock();
		
		meta.use();
		this.views.main.$el.show();
		setTimeout(function(){
			Global.scrollTo(0, 1);
		}, 25);
	},
	hide: function(){
		this.views.main.$el.hide();
		$('html').removeClass('webim-touch-html');
		meta.loss();
		sdk.screen.unlock();
	},
	
	//
	title: function(val){
		this.nav && this.nav.title(val);
	},
	
	// 启动
	start: function(page, data){
		var _this = this;
		
		this.show();

		var url = "";
		
		switch(page){
			case "contacts": {
				url = page;
			}; break;
			case "chat2": {
				url = page + '/' + data.uid + (data.pid ? ('/' + data.pid) : '');
				//this.title(data.userName);
			}; break;
			case "profile": {
				url = page + '/' + data.uid;
			}; break;
			default:;
		}
		
		url && this.forward(url);
		
		if(this.status === STATUS.STARTED || this.status === STATUS.STARTING){
			return;
		}

		// <!-- 从停止状态启动 -->
		this.status = STATUS.STARTING;
		this.trigger('statusChange', {status: this.status});
		
		// 初始化时开始出现加载图标
		this.loading.show();
		this.loading.text('Connecting');
		
		this.ready(function(){
			this.loading.hide();
			this.status = STATUS.STARTED;
			this.trigger('statusChange', {status: this.status});
			this.trigger('start');
		});
		
		this.startHistory();
		
		// 绑定原始路径路由 为隐藏im界面
		this.routes && !new RegExp("^" + config.path + "\\/(?:chat2|contacts|profile)").test(config.originalHash) && this.route(config.originalHash || "", "hide");

		// 初始化连接
		this.sdk.initConn();
		// 启动连接
		this.sdk.connect(function(){
			_this.login();
		});
	},

	stop: function(isRestart){
		this.hide();
		
		this.isReady = false;
		this.status = STATUS.STOPPING;
		this.trigger('statusChange', {status: this.status});
		
		!isRestart && this.stopHistory();
		this.sdk.disconnect();
		this.sdk.initProperties();
	},
	
	restart: function(){
		if(!this.isStarted()){
			return;
		}
		
		var args = [].slice.call(arguments);
		
		// 停止成功后 再启动
		this.once('stop', function(){
			this.start.apply(this, args);
		});
		
		this.stop();
		this.trigger('restart');
	},
	isStarted: function(){
		return this.status === STATUS.STARTED;
	},
	startHistory: function(){
		!this.isHistoryStart && Backbone.history.start();
		this.isHistoryStart = true;
	},
	stopHistory: function(){
		this.isHistoryStart && Backbone.history.stop();
		this.isHistoryStart = false;
	},
	/**
	 * 重新加载本地联系人数据
	 */
	reloadLocalContacts: function(users){
		this.models.contacts.reset(users || this.sdk.cache.get('contacts'));;
	}
});



// 触屏im 仅允许单例
var singleton = null;

var Webim = function(){
	if(singleton){
		return singleton;
	}
	
	return (singleton = new App());
};


module.exports = Webim;